import com.idol.bean.TimerAttribute;
import com.idol.bean.TimerContainer;
import com.idol.component.ConsumerComponent;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @author SupremeSir
 * @description
 * @className ConsumerMain
 * @date 2021/1/21 23:13
 **/
public class ConsumerMain {
    //线程池执
    private static ExecutorService executorService = Executors.newFixedThreadPool(200);

    public static void main(String[] args) throws InterruptedException, IOException {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConsumerConfigration.class);
        context.start();
        ConsumerComponent consumerComponent = context.getBean(ConsumerComponent.class);
        new Thread(() -> {
            while (true) {
                try {
                    TimeUnit.SECONDS.sleep(5);
                    System.out.println("---------------------------------------");
                    Map<String, TimerAttribute> container = TimerContainer.getContainer();
                    for (Map.Entry<String, TimerAttribute> entry : container.entrySet()) {
                        List<Integer> castTimeList = entry.getValue().getCastTimeList();
                        List<Long> timeList = entry.getValue().getTimeList();

                        List<Integer> removeIndexList = new ArrayList<>();
                        List<Integer> valList = new ArrayList<>();

                        long currentTime = System.currentTimeMillis();
                        for (int i = 0; i < timeList.size(); i++) {
                            // 登记过时记录的索引
                            if (timeList.get(i) < currentTime - 60000) {
                                removeIndexList.add(i);
                            }
                            // 剔除后来的数据
                            if (timeList.get(i) > currentTime) {
                                break;
                            }
                            // 存储符合条件的数据
                            valList.add(castTimeList.get(i));
                        }
                        // 对数据排序
                        Collections.sort(valList);

                        System.out.println(entry.getKey() + "方法的 TP90：" + valList.get((int) Math.floor(valList.size() * 0.9)) + "____" +
                                "TP99：" + valList.get((int) Math.floor(valList.size() * 0.99)));

                        // 移除过时数据  注意：索引类型必须为常量，不可使用包装类
                        if (removeIndexList.size() > 0) {
                            System.out.println("**清理过时记录**");
                            for (int i : removeIndexList) {
                                timeList.remove(i);
                                castTimeList.remove(i);
                            }
                        }

                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        System.out.println("敲击 Enter 执行请求");
        System.in.read();
        while (true) {
            Thread.sleep(25);
            executorService.execute(() -> {
                consumerComponent.sayHi("李银河");
            });
            executorService.execute(() -> {
                consumerComponent.sayBye("李银河");
            });
            executorService.execute(() -> {
                consumerComponent.sayGoodNight("李银河");
            });
        }
    }

    @Configuration
    @EnableDubbo
    @ComponentScan(basePackages = "com.idol.component")
    @PropertySource("classpath:/dubbo-consumer.properties")
    static class ConsumerConfigration {
    }
}
